package org.example.base.mqtt;

import org.example.device.mqtt.event.DeviceNotifyMqttEvent;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.integration.annotation.Gateway;
import org.springframework.integration.annotation.MessagingGateway;
import org.springframework.integration.mqtt.support.MqttHeaders;
import org.springframework.integration.support.MessageBuilder;
import org.springframework.messaging.Message;
import org.springframework.messaging.handler.annotation.Header;

import java.util.concurrent.CompletableFuture;

@MessagingGateway(defaultRequestChannel = "mqttOutboundExecutorChannel", errorChannel = "producerErrorChannel")
@ConditionalOnProperty(prefix = "mqtt", name = "enable", havingValue = "true")
public interface MqttMsgSendBaseService<T> {

    @Gateway(requestChannel = "mqttOutboundExecutorChannel")
    void send( T payload, @Header(MqttHeaders.TOPIC) String mqttTopic, @Header(MqttHeaders.QOS) Integer qos, @Header("clazz") Class<T> tClass);
    @Gateway
    void send(T payload, @Header(MqttHeaders.TOPIC) String mqttTopic, @Header("clazz") Class<T> tClass);

    @Gateway(requestChannel = "mqttOutboundExecutorChannel")
    void send(Message<T> message);

    /**
     * 发送消息
     * @param topic
     * @param payload
     * @param tClass
     * @param retained MQTT 支持保留消息（Retained Message），即当客户端订阅某个主题时，会立即接收到最近一次发布的保留消息
     */
    @Gateway(requestChannel = "mqttOutboundExecutorChannel")
    void send(T payload, @Header(MqttHeaders.TOPIC) String mqttTopic,  @Header("clazz") Class<T> tClass, @Header(MqttHeaders.RETAINED) Boolean retained);
    /**
     * 带返回值
     * @param topic
     * @param payload
     * @return
     */
    @Gateway(requestChannel = "mqttOutboundExecutorChannel", replyChannel = "mqttReplyChannel")
    CompletableFuture<Message<?>> sendAndReceive(T payload, @Header(MqttHeaders.TOPIC) String topic, @Header("clazz") Class<T> tClass);

    default Message<T> buildMessage(T payload, String topic, Class<T> tClass) {
        return MessageBuilder
                .withPayload(payload)
                .setHeader(MqttHeaders.TOPIC, topic)
                .setHeader("clazz", payload.getClass())
                .build();
    }
}
